﻿using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Data;
using Magellan.Utilities;

namespace Magellan.Controls.Conventions.Editors
{
    /// <summary>
    /// The default fallback implementation of a readonly <see cref="IEditorStrategy"/>. If no other strategy can 
    /// figure out how to edit a field, this editor makes a good fallback.
    /// </summary>
    public class ReadOnlyEditorStrategy : IEditorStrategy
    {
        /// <summary>
        /// Creates the appropriate editor from the context. If the return value is null, another
        /// <see cref="IEditorStrategy"/> will be asked. The returned value should be fully configured
        /// and bound.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>
        /// A control that will be used for editing the field, or null if this strategy cannot be
        /// used for this field.
        /// </returns>
        public object CreateEditor(FieldContext context)
        {
            var allAttributes = BuddyClassAttributeProvider.GetForProperty(context.SourceItem.GetType(), context.PropertyDescriptor,
                                                                           context.SourceItem);

            var content = new UITextBlock
            {
                Margin = new Thickness(0),
                Padding = new Thickness(0),
                VerticalAlignment = VerticalAlignment.Center
            };
            content.SetValue(TextBlock.TextTrimmingProperty, TextTrimming.CharacterEllipsis);
            content.SetValue(FrameworkElement.NameProperty, "View_" + context.PropertyName);
            content.SetValue(AutomationProperties.AutomationIdProperty, "View_" + context.PropertyName);

            context.Binding.Mode = BindingMode.OneWay;

            var displayFormatAttribute = allAttributes.OfType<DisplayFormatAttribute>().FirstOrDefault();
            if (displayFormatAttribute != null)
                context.Binding.StringFormat = displayFormatAttribute.DataFormatString;
            BindingOperations.SetBinding(content, TextBlock.TextProperty, context.Binding);

            var forceBindingTransfer = (Action<object>)delegate(object o)
            {
                var theField = (UITextBlock)o;
                var textBindingExpression =
                    BindingOperations.GetBindingExpression(theField, TextBlock.TextProperty);
                if (textBindingExpression == null)
                    return;

                textBindingExpression.UpdateSource();
            };

            content.Loaded += (o, e) => forceBindingTransfer(o);

            return content;
        }
    }
}